package com.cfp4cloud.cfp.knowledge.service.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cfp4cloud.cfp.common.core.constant.enums.YesNoEnum;
import com.cfp4cloud.cfp.common.core.util.R;
import com.cfp4cloud.cfp.knowledge.dto.AiSuggestionFieldResultDTO;
import com.cfp4cloud.cfp.knowledge.entity.AiDataFieldEntity;
import com.cfp4cloud.cfp.knowledge.entity.AiDataTableEntity;
import com.cfp4cloud.cfp.knowledge.mapper.AiDataFieldMapper;
import com.cfp4cloud.cfp.knowledge.mapper.AiDataTableMapper;
import com.cfp4cloud.cfp.knowledge.service.AiAssistantService;
import com.cfp4cloud.cfp.knowledge.service.AiDataFieldService;
import com.cfp4cloud.cfp.knowledge.service.AiDataService;
import com.cfp4cloud.cfp.knowledge.support.feign.RemoteTableInfoService;
import com.cfp4cloud.cfp.knowledge.support.provider.ModelProvider;
import dev.langchain4j.model.chat.ChatModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * AI数据字段管理服务实现类
 * <p>
 * 管理数据库表字段的元数据信息 支持字段同步、注释优化和AI智能评估 提供虚拟注释功能增强字段可读性
 *
 * @author cfp
 * @date 2025-03-26 21:49:03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AiDataFieldServiceImpl extends ServiceImpl<AiDataFieldMapper, AiDataFieldEntity>
		implements AiDataFieldService {

	/**
	 * 远程表信息服务 用于获取数据库表结构信息
	 */
	private final RemoteTableInfoService tableInfoService;

	/**
	 * 数据表数据访问层
	 */
	private final AiDataTableMapper aiDataTableMapper;

	/**
	 * 模型提供者 用于获取AI模型进行字段评估
	 */
	private final ModelProvider modelProvider;

	/**
	 * 数据服务（延迟加载） 避免循环依赖
	 */
	@Lazy
	private final AiDataService aiDataService;

	/**
	 * 字段数据访问层
	 */
	private final AiDataFieldMapper aiDataFieldMapper;

	/**
	 * 获取表字段信息
	 * <p>
	 * 如果字段信息不存在则自动同步 确保返回最新的字段元数据
	 * @param dsName 数据源名称
	 * @param tableName 表名
	 * @return 字段信息列表
	 */
	@Override
	public List<AiDataFieldEntity> getOrSync(String dsName, String tableName) {

		AiDataTableEntity dataTableEntity = aiDataTableMapper.selectOne(Wrappers.<AiDataTableEntity>lambdaQuery()
			.eq(AiDataTableEntity::getDsName, dsName)
			.eq(AiDataTableEntity::getTableName, tableName));

		List<AiDataFieldEntity> fieldEntityList = baseMapper.selectList(Wrappers.<AiDataFieldEntity>lambdaQuery()
			.eq(AiDataFieldEntity::getTableId, dataTableEntity.getTableId()));

		if (fieldEntityList.isEmpty()) {
			// 字段列表为空，执行同步操作
			syncTableField(dataTableEntity.getDsName(), dataTableEntity.getTableName());
			// 同步完成后重新查询
			fieldEntityList = baseMapper.selectList(Wrappers.<AiDataFieldEntity>lambdaQuery()
				.eq(AiDataFieldEntity::getTableId, dataTableEntity.getTableId()));
		}
		return fieldEntityList;
	}

	/**
	 * 同步表字段元数据
	 * <p>
	 * 从数据库获取最新字段信息并更新本地缓存 保留已有的自定义注释，仅更新系统注释
	 * @param dsName 数据源名称
	 * @param tableName 表名
	 * @return 同步成功返回true
	 */
	public boolean syncTableField(String dsName, String tableName) {
		// 查询数据表实体
		AiDataTableEntity dataTableEntity = aiDataTableMapper.selectOne(Wrappers.<AiDataTableEntity>lambdaQuery()
			.eq(AiDataTableEntity::getDsName, dsName)
			.eq(AiDataTableEntity::getTableName, tableName));
		R<List<Map<String, Object>>> listColumnR = tableInfoService.listColumn(dataTableEntity.getDsName(),
				dataTableEntity.getTableName());

		for (Map<String, Object> datum : listColumnR.getData()) {
			AiDataFieldEntity fieldEntity = new AiDataFieldEntity();
			fieldEntity.setTableId(dataTableEntity.getTableId());
			fieldEntity.setDsName(dataTableEntity.getDsName());
			fieldEntity.setDbType(MapUtil.getStr(datum, "databaseType"));
			fieldEntity.setFieldName(MapUtil.getStr(datum, "name"));
			fieldEntity.setFieldComment((String) datum.get("comment"));
			fieldEntity.setFieldType(MapUtil.getStr(datum, "originType"));
			fieldEntity.setModifyStatus(YesNoEnum.NO.getCode());

			this.getOneOpt(Wrappers.<AiDataFieldEntity>lambdaQuery()
				.eq(AiDataFieldEntity::getTableId, dataTableEntity.getTableId())
				.eq(AiDataFieldEntity::getFieldName, fieldEntity.getFieldName()), false).ifPresentOrElse(entity -> {
					// 字段已存在，仅更新系统注释
					entity.setFieldComment(fieldEntity.getFieldComment());
					baseMapper.updateById(entity);
				}, () -> baseMapper.insert(fieldEntity)); // 字段不存在，新增记录
		}

		return true;
	}

	/**
	 * 使用AI评估表字段质量
	 * <p>
	 * 异步分析表结构和字段信息 生成优化建议和改进的字段注释 更新虚拟注释供开发参考
	 * @param dsName 数据源名称
	 * @param tableName 表名
	 */
	@Override
	@Async
	public void assessTableField(String dsName, String tableName) {
		Triple<ChatModel, AiAssistantService, String> jsonAssistantTriple = modelProvider.getAiJSONAssistant(null);

		AiDataTableEntity dataTableEntity = aiDataTableMapper.selectOne(Wrappers.<AiDataTableEntity>lambdaQuery()
			.eq(AiDataTableEntity::getDsName, dsName)
			.eq(AiDataTableEntity::getTableName, tableName));

		String dataSchema = aiDataService.queryTableSchema(List.of(dataTableEntity));
		AiSuggestionFieldResultDTO aiSuggestionFieldResultDTO = jsonAssistantTriple.getMiddle()
			.assessTableField(dataSchema);
		log.info("评估表字段结果：{}", aiSuggestionFieldResultDTO);

		for (AiSuggestionFieldResultDTO.AiSuggestionFieldDTO suggestion : aiSuggestionFieldResultDTO.getSuggestions()) {
			AiDataFieldEntity aiDataFieldEntity = new AiDataFieldEntity();
			aiDataFieldEntity.setModifyStatus(YesNoEnum.YES.getCode());
			aiDataFieldEntity.setModifyTime(LocalDateTime.now());
			aiDataFieldEntity.setVirtualComment(suggestion.getFieldSuggestionComment());

			// 更新字段的虚拟注释
			aiDataFieldMapper.update(aiDataFieldEntity,
					Wrappers.<AiDataFieldEntity>lambdaQuery()
						.eq(AiDataFieldEntity::getTableId, dataTableEntity.getTableId())
						.eq(AiDataFieldEntity::getFieldName, suggestion.getFieldName()));
		}

		// 更新表的虚拟注释
		dataTableEntity.setVirtualComment(aiSuggestionFieldResultDTO.getTableSuggestionComment());
		aiDataTableMapper.updateById(dataTableEntity);
	}

}
